<?php
/**
 * Class UserLogic
 * @package app\common\logic
 */

namespace app\common\logic;
use think\Config;
use think\Exception;
use think\Log;

/**
 * 管理员用户逻辑（非普通用户）
 *
 * @package app\common\logic
 */
class User extends Base
{

    protected $userInfo;
    private $adminUserModel;
    private $adminUserGroupModel;
    private $userModel;

    public function __construct($data = [])
    {
        parent::__construct($data);

        $this->adminUserModel       = model('AdminUser');
        $this->adminUserGroupModel  = model('AdminUserGroup');
        $this->userModel            = model('User');
    }

    /**
     * 登录方法
     *
     * @author mayy
     * @date 2017-8-14
     * @param $user
     * @param $passwd
     * @param string $imei 手机唯一码
     * @param string $client_id 个推client_id
     * @throws Exception
     * @return array
     */
    public function login($user, $passwd, $imei = '', $client_id = '')
    {
        if (empty($user) || empty($passwd)) {
            exception('用户名和密码必须填写！');
        }

        $user_info = $this->adminUserGroupModel->getInfo(['username' => $user]);

        if (empty($user_info)) {
            exception('用户信息不存在！');
        }

        if (md5($passwd . Config::get('salt')) !== $user_info['password']) {
            exception('用户名或者密码错误！');
        }

        if ($user_info['status'] == 0) {
            exception('抱歉，此用户已被禁用！');
        }

        //生成token
        $token = $this->getUserToken($user_info['id'], USER_TYPE_ADMIN_USER);

        $this->userInfo = [
            'id'                => $user_info['id'],
            'username'          => $user_info['username'],
            'status'            => $user_info['status'],
            'last_login_time'   => $user_info['last_login_time'],
            'last_login_ip'     => $user_info['last_login_ip'],
            'role'              => $user_info['title'],
            'role_code'         => $user_info['code'],
            'upload_token'      => '',
            'token'             => $token,
            'receive_push'      => (int)$user_info['receive_push'],
        ];

        //登录成功后的操作
        $this->doAfterLogin($imei, $client_id);

        return $this->userInfo;
    }


    /**
     * 普通用户登录方法
     *
     * @author mayy
     * @date 2017-8-14
     * @param $user
     * @param $passwd
     * @param string $imei 手机唯一码
     * @param string $client_id 个推client_id
     * @throws Exception
     * @return array
     */
    public function normalUserLogin($user, $passwd, $imei = '', $client_id = '')
    {
        if (empty($user) || empty($passwd)) {
            exception('用户名和密码必须填写！');
        }

        $user_info = $this->userModel->getInfo(['username' => $user]);
        if (empty($user_info)) {
            exception('用户信息不存在！');
        }

        if (md5($passwd . Config::get('salt')) !== $user_info['password']) {
            exception('用户名或者密码错误！');
        }

        if ($user_info['status'] == 0) {
            exception('抱歉，您已被限制使用此软件！');
        }

        //生成token
        $token = $this->getUserToken($user_info['id'], USER_TYPE_NORMAL_USER);

        $this->userInfo = [
            'id'                => $user_info['id'],
            'username'          => $user_info['username'],
            'status'            => $user_info['status'],
            'last_login_time'   => $user_info['last_login_time'] ? $user_info['last_login_time'] : '',
            'last_login_ip'     => $user_info['last_login_ip'],
            'upload_token'      => '',
            'token'             => $token,
            'mobile'            => $user_info['mobile'],
            'email'             => $user_info['email'],
            'telphone'          => $user_info['telphone'],
            'company'           => $user_info['company'],
            'address'           => $user_info['address'],
            'create_time'       => $user_info['create_time'],
            'receive_push'      => (int)$user_info['receive_push'],
        ];

        //登录成功后的操作
        $this->doAfterNormalUserLogin($imei, $client_id);

        return $this->userInfo;
    }

    /**
     * 通过用户id获取用户的token
     *
     * @author mayy
     * @date 2017-8-14
     * @param $user_id
     * @param string $user_type 用户类型
     * @return string
     */
    private function getUserToken($user_id, $user_type = USER_TYPE_ADMIN_USER)
    {
        if ($user_id <= 0) {
            exception('缺少必要的参数！');
        }

        $token = $this->createUserToken($user_id, $user_type);

        $user_token_model = model('UserToken');
        $token_info = $user_token_model->getUserToken($user_id, $user_type);
        if (empty($token_info)) {
            //插入一条token
            $add_data = [
                'user_id'   => (int)$user_id,
                'user_type' => $user_type,
                'token'     => $token,
            ];
            $res = $user_token_model->addToken($add_data);
        } else {
            //更新token
            $update_data = [
                'token'     => $token,
            ];
            $res = $user_token_model->updateToken($token_info['token_id'], $update_data);
        }

        if ($res === false) {
            exception('更新token失败，请重试！');
        }

        /*
        if (is_browser()) {
            session('token_' . 'caretek', $token);
        }*/

        unset($user_token_model);
        return $token;
    }


    /**
     * 创建token
     *
     * @author mayy
     * @date 2017-8-14
     * @param $user_id
     * @param $user_type
     * @return string
     */
    private function createUserToken($user_id, $user_type)
    {
        if ($user_id <= 0) {
            exception('缺少必要的参数！');
        }
        return md5('userToken_' . $user_type . '_' . $user_id . '_' .time());
    }

    /**
     * 执行登录成功后的操作
     *
     * - 更新ip 、登录时间
     *
     * @author mayy
     * @date 2017-8-14
     * @param $imei
     * @param $client_id
     * @return void
     */
    private function doAfterLogin($imei = '', $client_id = '')
    {
        $update_data = [
            'last_login_time'   => NOW_DATE,
            'last_login_ip'     => get_client_ip(),
        ];

        if (!empty($imei)) {
            $update_data['imei'] = $imei;
        }

        if (!empty($imei)) {
            $update_data['client_id'] = $client_id;
        }

        $res = $this->adminUserModel->saveDate($this->userInfo['id'], $update_data);
        if (empty($res)) {
            exception('数据更新失败，请重试！');
        }

        //行为记录
        $log_res = $this->recordUserBehavior('api', 'user', 'login', $this->userInfo['id'], $this->userInfo['username']);
        if ($log_res == false) {
            exception('行为记录失败，请重试！');
        }
    }

    /**
     * 执行登录成功后的操作
     *
     * - 更新ip 、登录时间
     *
     * @author mayy
     * @date 2017-8-14
     * @param $imei
     * @param $client_id
     * @return void
     */
    private function doAfterNormalUserLogin($imei = '', $client_id = '')
    {
        $update_data = [
            'last_login_time'   => NOW_DATE,
            'last_login_ip'     => get_client_ip(),
        ];

        if (!empty($imei)) {
            $update_data['imei'] = $imei;
        }

        if (!empty($imei)) {
            $update_data['client_id'] = $client_id;
        }

        $res = $this->userModel->saveDate($this->userInfo['id'], $update_data);
        if (empty($res)) {
            exception('数据更新失败，请重试！');
        }
    }

    /**
     * 用户行为记录
     *
     * @author mayy
     * @date 2017-8-11
     * @param $module
     * @param $controller
     * @param $action
     * @param $user_id
     * @param $user_name
     * @return bool
     */
    public function recordUserBehavior($module, $controller, $action, $user_id, $user_name)
    {
        //检查不需要记录的操作
        $act = lcfirst($controller) . '.' . lcfirst(strtolower($action));
        $need_record = config('need_record_behavior_action');
        $need_record = $need_record ? $need_record : [];

        if (in_array($act, $need_record)) {
            $add_data = [
                'user_id'   => $user_id,
                'user_name' => $user_name,
                'module'    => $module,
                'controller'=> $controller,
                'action'    => $action,
            ];

            $user_behavior_model = model('UserBehaviorLog');
            $res = $user_behavior_model->recordBehaviorLog($add_data);
            if ($res == false) {
                Log::record('行为记录失败！' . $user_behavior_model->getLastSql());
                return false;
            }

            unset($user_behavior_model);
        }

        return true;
    }

    /**
     * 检查指定用户是否可以接受任务
     *
     * 1、用户是否存在
     * 2、用户角色是否可以接受任务
     *
     * @param $user_id
     * @return boolean
     */
    public function checkUserCanGetTask($user_id)
    {
        if ($user_id <= 0) {
            exception('缺少必要的参数！');
        }

        $user_info = $this->adminUserModel->getInfo(['id' => $user_id]);
        if (empty($user_info)) {
            exception('指定领取任务的用户不存在！');
        }

        if ($user_info['status'] == 0) {
            exception('指定领取任务的用户目前处于冻结状态！');
        }

        //TODO 角色判断

        return true;
    }

    /**
     * 通过用户id获取用户名
     *
     * @author mayy
     * @date 2017-9-6
     * @param $user_id
     * @return string
     */
    public function getUserNameById($user_id)
    {
        if ($user_id <= 0) {
            return "";
        }

        $user_info = $this->adminUserModel->getInfo(['id' => $user_id], 'username');
        return !empty($user_info) ? $user_info['username'] : "";
    }


    /**
     * 获取用户的app权限列表
     *
     * @param $user_id
     * @param boolean $is_app 为true检验app权限，否则检验后台权限
     * @param array $user_info
     * @return array
     */
    public function getUserAppAuthList($user_id, $is_app = true, array $user_info = [])
    {
        if ($user_id <=0) {
            return [];
        }

        if (empty($user_info) || !isset($user_info['app_rules'])) {
            $admin_user_group_model = model('AdminUserGroup');
            $user_info = $admin_user_group_model->getInfo(['id' => $user_id]);
        }

        $auth_ids = $is_app ? $user_info['app_rules'] : $user_info['rules'];
        if (empty($auth_ids)) {
            return [];
        }

        $auth_ids = explode(',', $auth_ids);
        $auth_ids = array_filter(array_unique($auth_ids));

        $auth_rule_model = $is_app ? model('AppAuthRule') : model('AuthRule');

        $where = [
            'id' => $auth_ids,
            'status' => 1,
            'son_rule' => true,
        ];
        $list = $auth_rule_model->getListByPage($where, build_limit(1, 500));
        if (empty($list['data'])) {
            return [];
        }

        $return = [];
        foreach ($list['data'] as $v) {
            //首字母都转成小写
            $name = implode('/', array_map("lcfirst", explode('/', $v['name'])));
            $return[] = $name;
        }

        return $return;
    }

    /**
     * 获取指定条件的厂家用户列表
     *
     * @param $params
     * @param bool $fields
     * @param int $limit
     * @return array
     */
    public function getUserList($params, $fields = true, $limit = 50)
    {
        $list = $this->adminUserGroupModel->getList($params, $limit, false, $fields);
        return $list['data'];
    }

    /**
     * 注册普通用户
     *
     * @author mayy
     * @date 2017-10-10
     * @param $username
     * @param $passwd
     * @param string $mobile
     * @param string $telphone 座机号码
     * @param string $company 公司名称
     * @param string $address 常用售后地址
     */
    public function registerNormalUser($username, $passwd, $mobile = '', $telphone = '', $company = '', $address = '', $email = '')
    {
        if (empty($username) || empty($passwd)) {
            exception('缺少必要的参数！');
        }

        //检查用户名是否已经被注册
        $info = $this->userModel->getInfo(['username' => $username], 'username');
        if (!empty($info)) {
            exception('用户名已经被注册！');
        }

        $user_info = [
            'username'  => $username,
            'password'  => md5($passwd . Config::get('salt')),
            'mobile'    => $mobile,
            'telphone'  => $telphone,
            'company'   => $company,
            'address'   => $address,
            'email'     => $email,
        ];

        $res = $this->userModel->addData($user_info);
        return $res;
    }


    /**
     * 获取经销商列表
     *
     * @param array $user_info
     * @param array $params
     * @param int $limit
     * @return mixed
     */
    public function getDealerList(array $user_info, array $params, $limit = 20)
    {
        if (empty($user_info)) {
            exception('请先登录！');
        }

        $params['code']     = 'dealer';
        $params['status']   = 1;

        $fields = 'id,username';
        $list = $this->adminUserGroupModel->getList($params, $limit, false, $fields);
        return null_to_empty_string($list);

    }

    /**
     * 编辑普通用户信息
     *
     * @author mayy
     * @date  2017-10-17
     * @param array $user_info
     * @param array $user_data
     * @return boolean
     */
    public function editNormalUser(array $user_info, array $user_data)
    {
        if (empty($user_info)) {
            exception('请先登录！');
        }

        if (empty($user_data)) {
            return true;
        }

        if (isset($user_data['username']) && !empty($user_data['username']) && $user_data['username'] != $user_info['username']) {
            //检查要变更的用户名是否已经存在
            $info = $this->userModel->getInfo(['username' => $user_data['username']], 'username');
            if (!empty($info)) {
                exception('用户名已存在！');
            }
        }

        //密码修改
        if (isset($user_data['password']) && !empty($user_data['password'])) {
            $user_data['password'] = md5($user_data['password'] . Config::get('salt'));
        }

        //数据修改：
        $res = $this->userModel->saveDate($user_info['id'], $user_data);
        if ($res === false) {
            return false;
        }

        return true;
    }

    /**
     * 获取仓库管理员列表
     *
     * @param array $params
     * @param int $limit
     * @return mixed
     */
    public function getStorageManagerList(array $params, $limit = 20)
    {
        $params['code']     = 'storage_principal';
        $params['status']   = 1;

        $fields = 'id,username';
        $list = $this->adminUserGroupModel->getList($params, $limit, false, $fields);
        return $list['data'];
    }

    /**
     * 获取指定角色人员列表
     *
     * @param string $code 角色code
     * @param int $limit
     * @return mixed
     */
    public function getRolePersonList($code, $limit = 20)
    {
        if (empty($code)) {
            return [];
        }

        $params['code']     = $code;
        $params['status']   = 1;

        $fields = 'id,username';
        $list = $this->adminUserGroupModel->getList($params, $limit, false, $fields);
        return $list['data'];
    }

    /**
     * 设置用户是否接收消息
     *
     * @param array $user_info
     * @param string $user_type 用户类型
     * @param int $is_receive_push 是否接收推送消息
     * @return boolean
     */
    public function changeIfReceiveMsg(array $user_info, $user_type, $is_receive_push)
    {
        if (empty($user_info)) {
            exception('请先登录！');
        }

        switch ($user_type) {
            case USER_TYPE_ADMIN_USER:
                $user_model = model('AdminUser');
                break;
            case USER_TYPE_NORMAL_USER:
                $user_model = model('User');
                break;
            default:
                Log::record('用户类型参数错误：' . $user_type);
                exception('用户类型参数错误');
        }
        $user_info = $user_model->getInfo(['id' => $user_info['id']], 'id,receive_push');
        if (empty($user_info)) {
            Log::record('用户('.$user_info['id'] .': '.$user_type.')不存在');
            exception('用户信息不存在！');
        }

        if ($is_receive_push == $user_info['receive_push']) {
            return true;
        } else {
            $res = $user_model->saveDate($user_info['id'], ['receive_push' => $is_receive_push]);
            return $res === false ? false : true;
        }
    }
}